﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Cofe.Core.Actions
{
    [Export(typeof(ICofeService))]
    [ServicePriority(ServicePriorityAttribute.DefaultPriority_COFE)]
    public class CofeTransferManager : ITransferManager
    {
        #region Constructor

        #endregion

        #region Methods


        public async Task<ICofeSystemInfo> RenameAsync(ICofeSystemInfo entry, ICofeDirectoryInfo fromm,
            string newName, IProgress<ProgressEventArgs> progress, System.Threading.CancellationToken cts)
        {
            TransferMode resultMode = TransferMode.None;

            foreach (var h in TransferHelpers)
            {
                if (h.GetSupportedMode(new ICofeSystemInfo[] { entry }, fromm, fromm).HasFlag(TransferMode.Rename))
                {
                    resultMode = await h.RenameAsync(TransferMode.Rename, entry, fromm, newName, progress, cts);
                    if (resultMode == TransferMode.Rename)
                        break;
                }
            }

            if (resultMode != TransferMode.Rename)
                throw new NotSupportedException("No helper found for renaming " + entry.Name);

            return await EntryFE.TryParsePathAsync(PathFE.Combine(fromm.ParseName, newName));
        }

       
        public async Task<ICofeSystemInfo[]> TransferAsync(TransferMode mode, ICofeSystemInfo[] entries, 
            ICofeDirectoryInfo fromm, ICofeDirectoryInfo too, IProgress<ProgressEventArgs> progress, CancellationToken cts)
        {
            if (entries.Length == 0)
                return new ICofeSystemInfo[] { };

            TransferMode resultMode = TransferMode.None;

            List<ICofeSystemInfo> retList = new List<ICofeSystemInfo>();

            foreach (var h in TransferHelpers)
            {
                if (h.GetSupportedMode(entries, fromm, too).HasFlag(mode))
                {
                    resultMode = await h.TransferAsync(mode, entries, fromm, too, progress, cts);
                    if (resultMode != TransferMode.None)
                        break;
                }
            }

            if (resultMode == TransferMode.None)
            {
                string itemStr = (entries.Length == 1) ? entries[0].Name : entries.Length.ToString() + " items.";
                throw new NotSupportedException("No helper found for transfering " + itemStr);
            }

            var entryNameList = (from entry in entries 
                               select PathFE.Combine(too.ParseName, entry.Name)).ToList();
            List<string> notTransferred = new List<string>(entryNameList);

            //await too.RefreshAsync();
            foreach (var addedEntry in too.EnumerateCofeSystemInfos(EntryConstructionFlags.DefaultWithoutCache))
                if (entryNameList.Contains(addedEntry.ParseName))
                {
                    retList.Add(addedEntry);
                    notTransferred.Remove(addedEntry.ParseName);
                }

            if (notTransferred.Count > 0)
                CofeServices.Logger.Log(String.Format("CTM: Some items may not be transferred correctly {0}",
                    string.Join(",", notTransferred.ToArray())), Category.Warn, Priority.Low);

            //foreach (var entry in entries)
            //    retList.Add(await EntryFE.TryParsePathAsync(PathFE.Combine(too.ParseName, entry.Name)));

            return retList.ToArray();

        }


       
        #endregion

        #region Data

        ITransferHelper[] _transferHelpers = null;

        #endregion

        #region Public Properties


        public ITransferHelper[] TransferHelpers
        {
            get { return _transferHelpers != null ? _transferHelpers : CofeServices.ServiceLocater.FindAllServices<ITransferHelper>().ToArray(); }
            set { _transferHelpers = value; }
        }

        #endregion




    }

}
